今天是這次鐵人賽的尾聲
我們要再來介紹 Rust 中的測試
昨天介紹的測試是單元測試,不過還要再另外補充 private method 的測試
不曉得各位在測試的時候會不會測 private method
,有些人覺得需要,有些人可能覺得不用
不管需不需要, Rust 是可以支援 private method
測試的
跟其他的單元測試都是一樣,一樣要標註 test 屬性
我們來試試
fn calculator_private(a: i32, b: i32) -> i32 {
let result = a + b;
result
}
#[cfg(test)]
mod tests {
use super::calculator_private;
#[test]
fn calculator_test() {
assert_eq!(4, calculator_private(2, 2));
}
}
> cargo test
Running unittests src/main.rs (target/debug/deps/hello_world-9a6d4baccdd90e29)
running 1 test
test tests::internal ... ok
test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
在 Rust 中,會把整合測試放在 tests
目錄底下
Cargo 會自動搜尋 tests
底下的測試文件
所以我們也不需要用 #[cfg(test)]
告訴 Cargo 這個是測試檔案了
我來把昨天的測試搬到 tests 檔案底下,tests 要與 src 平行 (放在根目錄底下)
# tests/calculator_test.rs
#[test]
fn test_addition() {
let result = calculator::addition(1, 2);
assert!(result.eq(&3), "你的運算結果不等於 {}", 4)
}
跑測試下去,錯了,他找不到 calculator 這個 module
> cargo test
error[E0433]: failed to resolve: use of undeclared crate or module `calculator`
--> tests/calculator_test.rs:5:18
|
5 | let result = calculator::addition(1, 2);
| ^^^^^^^^^^ use of undeclared crate or module `calculator`
那我們用 use 把他加進來看看
use hello_world::calculator;
#[test]
fn test_addition() {
let result = calculator::addition(1, 2);
assert!(result.eq(&3), "你的運算結果不等於 {}", 4)
}
這次跑下去還是錯了,不過錯誤訊息更清楚了,他寫著,他在根目錄找不到 calculator 這個 module
> cargo test
error[E0432]: unresolved import `hello_world::calculator`
--> tests/calculator_test.rs:1:5
|
1 | use hello_world::calculator;
| ^^^^^^^^^^^^^^^^^^^^^^^ no `calculator` in the root
For more information about this error, try `rustc --explain E0432`.
這是因為我們把 calculator 放在 main.rs 中了
在 Rust 中,
main.rs 是用來執行程式碼的,
lib.rs 才是用來放功能程式碼的,
而我們測試應該都是測功能,應該將功能程式碼放在 lib.rs 中才對
# src/lib.rs
pub mod calculator {
pub fn addition(a: i32, b: i32) -> i32 {
let result = a + b;
result
}
}
我們可以看到下面這一串
編譯的時候會去看整個專案中的測試
首先是看 src/lib.rs
中的測試
其次是看 src/main.rs
中的測試
最後是看 tests
中的測試
單元測試都會放在 src/lib.rs
以及 src/main.rs
中
而跨模組或者功能性的整合測試,就會放在 tests
> cargo test
Running unittests src/lib.rs (target/debug/deps/hello_world-a01c1fd1ce8393ba)
running 0 tests
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
Running unittests src/main.rs (target/debug/deps/hello_world-9a6d4baccdd90e29)
running 0 tests
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
Running tests/calculator_test.rs (target/debug/deps/calculator_test-77b32a48a24a9faf)
running 1 test
test test_addition ... ok
test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
Doc-tests hello_world
running 0 tests
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
Rust 也提供了很多的測試的評估方法
像是我們昨天用到的 assert!
assert_eq!
今天我們再多來介紹 1 個 以及 debug 模式下執行的評估方法
判斷兩者之間的值是否不相等,以剛剛的例子來看
如果我們把第一個參數改成 4 ,就會失敗,改成 4 以外的值,就會成功
fn calculator_private(a: i32, b: i32) -> i32 {
let result = a + b;
result
}
#[cfg(test)]
mod tests {
use super::calculator_private;
#[test]
fn internal() {
assert_ne!(5, calculator_private(2, 2));
}
}
我們在什麼時候會需要在 Debug 模式下跑測試呢
而他們的用法跟 assert!
assert_eq!
assert_ne!
沒有什麼不同
我們可以直接在開發模式知道測試的結果,跟 test 模式不一樣的是,他只會運行 main.rs 裡面的程式碼
且在 release 的時候不會運行
fn main() {
fn calculator_private(a: i32, b: i32) -> i32 {
let result = a + b;
result
}
debug_assert_eq!(5, calculator_private(1, 2));
}